package com.loongtech.core.util;

import com.loongtech.bi.entity.system.EntityMonitorConfig;
import com.loongtech.bi.manager.system.DailyReportJobFactory;
import com.loongtech.bi.manager.system.JobFactory;
import com.loongtech.bi.manager.system.SyncServerJobFactory;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

public class ScheduleUtils {
    private static final Logger LOG = LoggerFactory.getLogger(ScheduleUtils.class);

    /**
     * 获取触发器key
     *
     * @param id:
     * @return :
     */
    private static TriggerKey getTriggerKey(String id) {

        return TriggerKey.triggerKey(id);
    }

    /**
     * 获取表达式触发器
     *
     * @param scheduler the scheduler
     * @param id        the job name
     * @return cron trigger
     */
    public static CronTrigger getCronTrigger(Scheduler scheduler, String id) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(id);
            return (CronTrigger) scheduler.getTrigger(triggerKey);
        } catch (SchedulerException e) {
            LOG.error("获取定时任务CronTrigger出现异常", e);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 创建任务
     *
     * @param scheduler   the scheduler
     * @param scheduleJob the schedule job
     */
    public static void createScheduleJob(Scheduler scheduler, EntityMonitorConfig scheduleJob) {
        if (scheduleJob.getEndTime().getTime() > System.currentTimeMillis()) {
            createScheduleJob(scheduler, scheduleJob.getId().toString(), scheduleJob);
        }
    }

    /**
     * 创建定时任务
     *
     * @param scheduler the scheduler
     *                  the cron expression
     * @param param     the param
     */
    private static void createScheduleJob(Scheduler scheduler, String id, EntityMonitorConfig param) {
        // 同步或异步
        Class<? extends Job> jobClass = JobFactory.class;

        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(id).build();

        // 放入参数，运行时的方法可以获取
        jobDetail.getJobDataMap().put(id, param);

        // 表达式调度构建器
        SimpleTrigger trigger = newTrigger().withIdentity(id).startAt(param.getStartTime())
                .endAt(param.getEndTime())
                .withSchedule(simpleSchedule().withIntervalInMinutes(param.getIntervalTime())
                        .withRepeatCount(param.getCountNum() == null ? Integer.MAX_VALUE : param.getCountNum()))
                .build();
        // CronScheduleBuilder scheduleBuilder =
        // CronScheduleBuilder.cronSchedule(cronExpression);
        //
        // // 按新的cronExpression表达式构建一个新的trigger
        // CronTrigger trigger =
        // TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            LOG.error("创建定时任务失败", e);
            // deleteScheduleJob(scheduler, id);
            e.printStackTrace();
        }
    }

    /**
     * 创建获取服务器列表定时任务
     *
     * @param scheduler:
     */
    public static void createSyncServerScheduleJob(Scheduler scheduler, String id, Date startDate, Date endDate, int interval, int prpeat) {
        Class<? extends Job> jobClass = SyncServerJobFactory.class;

        // 构建job信息
        if (null == id) {
            return;
        }
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(id).build();

        // 放入参数，运行时的方法可以获取
        jobDetail.getJobDataMap().put(id, null);

        // 表达式调度构建器
        SimpleTrigger trigger = newTrigger().withIdentity(id).startAt(startDate).endAt(endDate).withSchedule(simpleSchedule().withIntervalInMinutes(interval).withRepeatCount(prpeat)).build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            LOG.error("创建获取服务器列表的定时任务失败", e);
        }
    }

    /**
     * 创建获取每日报表定时任务
     *
     * @param scheduler:
     */
    public static void createDailyReportScheduleJob(Scheduler scheduler, String id, Date startDate, Date endDate, int interval, int prpeat) {
        System.out.println("[每日报表] 开始执行--------------------- startDate: " + startDate + "endDate: " + endDate + "interval" + interval);
        Class<? extends Job> jobClass = DailyReportJobFactory.class;
        if (null == id) {
            return;
        }
        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(id).build();
        // 放入参数，运行时的方法可以获取
        jobDetail.getJobDataMap().put(id, null);
        // 表达式调度构建器
        SimpleTrigger trigger = newTrigger().withIdentity(id).startAt(startDate)
                .endAt(endDate)
                .withSchedule(simpleSchedule().withIntervalInHours(interval)
                        .withRepeatCount(prpeat)).build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            LOG.error("创建定时任务失败", e);
        }
    }

    /**
     * 运行一次任务
     *
     * @param scheduler:
     * @param id:
     */
    public static void runOnce(Scheduler scheduler, String id) {
        JobKey jobKey = JobKey.jobKey(id);
        try {
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            LOG.error("运行一次定时任务失败", e);
            e.printStackTrace();
        }
    }

    /**
     * 暂停任务
     *
     * @param scheduler:
     * @param id:
     */
    public static void pauseJob(Scheduler scheduler, String id) {

        JobKey jobKey = JobKey.jobKey(id);
        try {
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            LOG.error("暂停定时任务失败", e);
            e.printStackTrace();
        }
    }

    /**
     * 恢复任务
     *
     * @param scheduler:
     */
    public static void resumeJob(Scheduler scheduler, EntityMonitorConfig entity) {

        JobKey jobKey = JobKey.jobKey(entity.getId().toString());
        try {
            if (scheduler.checkExists(jobKey)) {
                scheduler.resumeJob(jobKey);
            } else {
                createScheduleJob(scheduler, entity);
            }
        } catch (SchedulerException e) {
            LOG.error("暂停定时任务失败", e);
            e.printStackTrace();
        }
    }

    /**
     * 获取jobKey
     * <p>
     * the job name
     * the job group
     *
     * @return the job key
     */
    public static JobKey getJobKey(String id) {

        return JobKey.jobKey(id);
    }

    /**
     * 更新定时任务
     *
     * @param scheduler   the scheduler
     * @param scheduleJob the schedule job
     */
    public static void updateScheduleJob(Scheduler scheduler, EntityMonitorConfig scheduleJob) {
        updateScheduleJob(scheduler, scheduleJob.getId().toString(), scheduleJob);
    }

    /**
     * 更新定时任务
     *
     * @param scheduler the scheduler
     * @param id        the job name
     *                  the cron expression
     *                  the is sync
     * @param param     the param
     */
    private static void updateScheduleJob(Scheduler scheduler, String id, EntityMonitorConfig param) {

        // 同步或异步
        // Class<? extends Job> jobClass = isSync ? JobSyncFactory.class :
        // JobFactory.class;

        try {
            // JobDetail jobDetail = scheduler.getJobDetail(getJobKey(jobName,
            // jobGroup));

            // jobDetail = jobDetail.getJobBuilder().ofType(jobClass).build();

            // 更新参数 实际测试中发现无法更新
            // JobDataMap jobDataMap = jobDetail.getJobDataMap();
            // jobDataMap.put(ScheduleJobVo.JOB_PARAM_KEY, param);
            // jobDetail.getJobBuilder().usingJobData(jobDataMap);

            TriggerKey triggerKey = ScheduleUtils.getTriggerKey(id);

            SimpleTrigger trigger = newTrigger().withIdentity(id).startAt(param.getStartTime())
                    .endAt(param.getEndTime())
                    .withSchedule(simpleSchedule().withIntervalInMinutes(param.getIntervalTime())
                            .withRepeatCount(param.getCountNum() == null ? Integer.MAX_VALUE : param.getCountNum()))
                    .build();
            // 表达式调度构建器
            // CronScheduleBuilder scheduleBuilder =
            // CronScheduleBuilder.cronSchedule(cronExpression);
            //
            // CronTrigger trigger = (CronTrigger)
            // scheduler.getTrigger(triggerKey);

            // 按新的cronExpression表达式重新构建trigger
            // trigger =
            // trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            LOG.error("更新定时任务失败", e);
            e.printStackTrace();
        }
    }

    /**
     * 删除定时任务
     *
     * @param scheduler:
     * @param id:
     */
    public static void deleteScheduleJob(Scheduler scheduler, String id) {
        try {
            scheduler.deleteJob(getJobKey(id));
        } catch (SchedulerException e) {
            LOG.error("删除定时任务失败", e);
            e.printStackTrace();
        }
    }
}
